
'use strict';



let firstTab = true;

//文字效果列表，实时更新
let statusDict = {
	'fontsize': "18",
	'fontstyle': "微软雅黑",
	'fontcolor': "333333",
	'bold': false,
	'italic': false,
	'underline': false,
	'background': 'transparent',
};

//失去焦点前的光标位置存储
let cHead = null;
let blurOrNot = false;

//属性列表
let attrs = ['fontsize', 'fontstyle', 'fontcolor', 'bold', 'italic', 'underline'];

//参数修改判断
let setupOrNot = false;

let currentHeight = -1;

let paintOrText = true;
let partition = [2, 3, 7];

$(function(){
	init();

	currentHeight = $("#contentInput")[0].scrollHeight;

	$("#contentInput").keydown((e)=>{
		//初始化
		if($("#contentInput").children().length == 0)
		{
			init();
		}
		else if($("#contentInput p:eq(0)").children().length == 1 && $("#contentInput p:eq(0)").children()[0].nodeName=='BR')
		{
			$("#contentInput p:eq(0)").html("");
			insertSpan($("#contentInput p:eq(0)"));
		}

		let [head, range, ele] = cursorInfo() ? cursorInfo() : [null, null, null];
		if(ele && ele.html().length > 1 && ele.html().charCodeAt(0) == 8203)
		{
			ele.html(ele.html().substring(1, ele.html().length));
			setFocus(ele);
		}

		if(!range)
			return;
		else if(elementIsCode(ele))
			return;

/**
		//在非行首标签的开头输入时，焦点切换到上一个标签以使得逻辑更为自然
		if(range.collapsed && range.startOffset == 1 && !isLineStart(head, ele) && !setupOrNot)
		{
			let prev = prevSpan(ele);

			if(prev[0])
			{
				setFocus(prev);
			}
		}
**/
		if(setupOrNot)
		{
			insertSpan();
			setupOrNot = false;
		}

		//判断高度变化事件
		let tempHeight = $("#contentInput")[0].scrollHeight;
		if(tempHeight != currentHeight)
		{
			repaintCanvas(tempHeight);
			currentHeight = tempHeight;
		}
	});


	//事实更新光标位置的状态字典
	$("#contentInput").click(()=>{
		let [head, range, ele] = cursorInfo() ? cursorInfo() : [null, null, null];
		if(range)
		{
			if(elementIsCode(ele))
				return;
			if(!setupOrNot)
			{
				updateSpan();
			}
		}

	});

	//为字体设置按钮添加监听器
	$("#fontcolorSetting").change(function(){
		setFontColor($(this));
	});

	//以下四组函数用于同步字号、字型的输入和下拉框对照，目前仅支持单边逻辑，等待完善中
	$("#fontsizeSetting").change(function(){
		$("#fontsizeSettingInput").val($(this).val());
		setFontSize($(this));
	});

	$("#fontsizeSettingInput").change(function(){
		$("#fontsizeSetting").val($(this).val());
		setFontSize($(this));
	});

	$("#fontstyleSetting").change(function(){
		$("#fontstyleSettingInput").val($(this).val());
		setFontFamily($(this));
	});

	$("#fontstyleSettingInput").change(function(){
		$("#fontstyleSetting").val($(this).val());
		setFontFamily($(this));
	});
	//增加字体样式的触发事件
	$("#italicSetting").click(function(){
		setFontStyle($(this));
		setClickEffect($(this));
	});

	$("#boldSetting").click(function(){
		setFontStyle($(this));
		setClickEffect($(this));
	});

	$("#underlineSetting").click(function(){
		setFontStyle($(this));
		setClickEffect($(this));
	});

	//输入框失焦事件，以维系光标的存在
	$("#contentInput").blur(()=>{
		blurOrNot = true;
		cursorInfo();
	});
	$("#contentInput").focus(()=>{
		blurOrNot = false;
		cHead = null;
	});

});


//功能函数块

//初始化光标
function init()
{
	let start = $("<p></p>");
	let initSpan = createSpan();
	initSpan.html("&#8203;");
	start.append(initSpan);
	$("#contentInput").append(start);
	setFocus(initSpan);
}

//移入移出点击效果 效果暂定
function setClickEffect(obj)
{
	if(obj.hasClass('tool_unclicked'))
	{
		obj.addClass('tool_clicked');
		obj.removeClass('tool_unclicked');
	}
	else
	{
		obj.removeClass('tool_clicked');
		obj.addClass('tool_unclicked');
	}
}

//控制光标位置
function setFocus(el) {
    el = el[0]; 
    el.focus();
    var range = document.createRange();
    range.selectNodeContents(el);
    range.collapse(false);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
}

//判断是否为代码框
function elementIsCode(ele)
{
	if(ele[0].nodeName == 'DIV' && ele.attr('type')=='code')
	{
		return true;
	}
	return false;
}

//判断是否为行首元素
function isLineStart(head, ele)
{
	if(head.children()[0] == ele)
		return true;
	return false;
}


//更新对应的按键和字体
function updateBtn()
{
	//console.log(Object.assign({}, statusDict));
	for(let state in statusDict)
	{
		let id = '#' + state + 'Setting';
		switch(state)
		{
			case 'fontcolor':
				$(id).val(statusDict[state]);
				break;
			case 'fontsize':
			case 'fontstyle':
				$(id).val(statusDict[state]);
				$(id + 'Input').val(statusDict[state]);
				break;
			case 'bold':
			case 'italic':
			case 'underline':
				if(statusDict[state])
				{
					$(id).removeClass('tool_unclicked');
					$(id).addClass('tool_clicked');
				}
				else
				{
					$(id).addClass('tool_unclicked');
					$(id).removeClass('tool_clicked');
				}
				break;
		}
	}	
}

//设置各类字体效果

//设置字号
function setFontSize(obj)  
{  
	statusDict['fontsize'] = obj.val();
	setupOrNot = true;
} 

//设置字体颜色
function setFontColor(obj)  
{  
	statusDict['fontcolor'] = obj.val();
	setupOrNot = true;
}  

//设置字体风格----加粗/斜体/下划线
function setFontStyle(obj)  
{  
	let value = obj.attr('value');
	statusDict[value] = !statusDict[value];
	setupOrNot = true;
}  

//设置字体类型
function setFontFamily(obj)  
{  
	statusDict['fontstyle'] = obj.val();
	setupOrNot = true;
}

//获取光标悬停点的信息
function cursorInfo(){
	let selection = window.getSelection();
	
	if(selection.focusNode == 'DIV' || selection.anchorNode == null)
		return;
	let range = selection.getRangeAt(0),
		ele = range.commonAncestorContainer,
		res = null;

	if(ele.nodeType == 1 && ele.nodeName == 'DIV')
		return;

	if(ele.nodeType == 3)
	{
		ele = ele.parentNode;
	}
	res = $(ele).parent();

	if(blurOrNot)
	{
		if(cHead)
		{
			res = cHead;
		}
		else
		{
			cHead = res;
		}
	}

	return [$(res), range, $(ele)];
}



//根据当前的状态字典创建对应的文本块
function createSpan()
{
	let style = "";

	style += "font-size: " + statusDict['fontsize'] + "px; ";
	style += "font-family: '" + statusDict['fontstyle'] + "'; ";
	style += "color: #" + statusDict['fontcolor'] + "; ";
	style += "background-color: " + statusDict['background'] + "; ";
	style += "font-weight: " + (statusDict['bold'] ? "bold" : "normal") + "; ";
	style += "font-style: " + (statusDict['italic'] ? "italic" : "normal") + "; ";
	style += "text-decoration: " + (statusDict['underline'] ? "underline" : "normal") + ";";
	let span = $("<span></span>");
	span.attr('style', style);
	span.html("&#8203;");
	return span;
}

//将一个节点分裂为两个
function splitSpan(element, offset)
{
	let style = element.attr('style');
	let text = element.text();
	let length = text.length;
	let spanA = $("<span></span>");
	let spanB = $("<span></span>");
	spanA.attr('style', style);
	spanB.attr('style', style);
	spanA.text(text.substring(0, offset));
	spanB.text(text.substring(offset, length));

	return [spanA, spanB];
}

function insertSpan(start=null)
{
	if(start)
	{
		start.append(createSpan());
	}
	else
	{
		let [,range,ele] = cursorInfo();
		if(!range)
			return;
		let index = ele.index();
		let [insertPoint, afterSpan] = splitSpan(ele, range.startOffset);
		let span = createSpan();

		if(index == 0)
		{
			if(afterSpan.html() != "")
				ele.parent().append(insertPoint, span, afterSpan);
			else
				ele.parent().append(insertPoint, span);
		}
		else
		{
			if(afterSpan.html() != "")
				ele.prev().after(insertPoint, span, afterSpan);
			else
				ele.parent().append(insertPoint, span);
		}
		setFocus(span);
		ele.remove();
	}
}

function prevSpan(element)
{
	let ptr = element;

	if(ptr[0].nodeName == 'P')
	{
		if(ptr.children().length != 0)
			return ptr.children()[ptr.children().length-1];
		else
		{
			if(ptr.index() == 0)
				return null;
			else
				return prevSpan(ptr.prev());
		}
	}
	if(ptr.index() != 0)
		return ptr.prev();
	else
	{
		return prevSpan(ptr.parent());
	}
}

//剪枝逻辑 true:向前剪枝 false:向后剪枝，保留当前节点
function cutLeaves(head, index, reverse=false)
{
	let childrens = head.children();

	if(reverse)
	{
		for(let i = 0; i < index; i++)
			childrens[i].remove();
	}
	else
	{
		for(let i = index + 1; i < childrens.length; i++)
			childrens[i].remove();
	}
}

function updateSpan()
{
	let [,range,ele] = cursorInfo();
	if(!ele)
		return;

	let style = ele.attr('style');

	let styleReg = /font-size: (.*)px; font-family: '(.*)'; color: #(.*); background-color: (.*); font-weight: (.*); font-style: (.*); text-decoration: (.*);/
	let match = styleReg.exec(style);
	if(match)
	{
		statusDict['fontsize'] = match[1];
		statusDict['fontstyle'] = match[2];
		statusDict['fontcolor'] = match[3];
		statusDict['background'] = match[4];
		statusDict['bold'] = match[5] == 'bold' ? true : false;
		statusDict['italic'] = match[6] == 'italic' ? true : false;
		statusDict['underline'] = match[7] == 'underline' ? true : false;
		updateBtn();
	}
}
